package com.hu.bgp.server;

import java.io.File;
import java.util.ArrayList;

import org.apache.commons.vfs.FileChangeEvent;
import org.apache.commons.vfs.FileListener;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.VFS;
import org.apache.commons.vfs.impl.DefaultFileMonitor;

import com.hu.bgp.exceptions.BgpServerException;
import com.hu.bgp.util.ExtensionOnlyFilter;

class BarFileSystemWatcher
{

	private DefaultFileMonitor fsMonitor;

	private ArrayList<String> fileExtensions = new ArrayList<String>();
	private BgpConfiguration configuration;
	private GameTypeCollection gameTypeCollection;

	public BarFileSystemWatcher addFileExtension(String extension)
	{
		fileExtensions.add(extension);
		return this;
	}

	public void deleteFileExtension(String extension)
	{
		fileExtensions.remove(fileExtensions.indexOf(extension));
	}

	public BarFileSystemWatcher(BgpConfiguration configuration, GameTypeCollection gameTypeCollection)
	{
		fsMonitor = new DefaultFileMonitor(new BarListener());
		this.configuration = configuration;
		setBarDirectory(configuration.getBarRootPath());
		this.gameTypeCollection = gameTypeCollection;
		loadAllInto();
	}

	// TODO DIR exceptions dubbel op ff netjes maken...
	private void setBarDirectory(String path)
	{

		FileObject listendir = null;
		try
		{	
			FileSystemManager fsManager = VFS.getManager();
			listendir = fsManager.resolveFile(path);
			fsMonitor.addFile(listendir);
		}
		catch (FileSystemException e)
		{
			throw new BgpServerException("Error setting the bar source directory. check BGP config!", e);
		}

		DefaultFileMonitor fm = new DefaultFileMonitor(new BarListener());
		// fm.setRecursive(true);
		fm.addFile(listendir);
	}

	private void loadAllInto()
	{
		File barRootDir = new File(configuration.getBarRootPath());
		if (!barRootDir.exists())
			throw new BgpServerException("Invalid bar dir: " + barRootDir + " does not exist. Check BGP Configuration");
		barLoop: for (File barArchive : barRootDir.listFiles(new ExtensionOnlyFilter(".jar")))
		{
			GameType gt = new GameType(barArchive, configuration.getBarExtractRootPath(), configuration.getBarConfigFilename());
			gameTypeCollection.add(gt);
		}
	}

	public void start()
	{
		fsMonitor.start();
	}

	public void stop()
	{
		fsMonitor.stop();
	}

	private boolean isValidExtension(String extension)
	{

		if (fileExtensions.contains(extension))
			return true;
		return false;
	}

	class BarListener implements FileListener
	{
		public BarListener()
		{

		}

		public void fileChanged(FileChangeEvent arg0) throws Exception
		{
			// TODO Auto-generated method stub

		}

		public void fileCreated(FileChangeEvent arg0) throws Exception
		{
			// TODO Incomplete method
			System.out.println("DEBUG mkl] FileCreated! : " + arg0.getFile().getName());
			if (isValidExtension(arg0.getFile().getName().getExtension()))
			{
				File barArchive = new File(arg0.getFile().getName().getPath());
				gameTypeCollection.add(new GameType(barArchive, configuration.getBarExtractRootPath(), configuration.getBarConfigFilename()));

			}
		}

		public void fileDeleted(FileChangeEvent arg0) throws Exception
		{
			// TODO Auto-generated method stub

		}
	}
}
